/**
 * 多端文件上传工具
 */
import platform from './platform.js'
import config from '../config.js'

// 选择图片
export const chooseImage = (options = {}) => {
  const defaultOptions = {
    count: 9,
    sizeType: ['original', 'compressed'],
    sourceType: ['album', 'camera']
  }
  
  return new Promise((resolve, reject) => {
    // #ifdef MP-WEIXIN
    // 微信小程序使用chooseMedia
    uni.chooseMedia({
      count: options.count || defaultOptions.count,
      mediaType: ['image'],
      sourceType: options.sourceType || defaultOptions.sourceType,
      camera: 'back',
      success: (res) => {
        const tempFiles = res.tempFiles.map(file => ({
          path: file.tempFilePath,
          size: file.size,
          name: file.name || `image_${Date.now()}.jpg`
        }))
        resolve({ tempFilePaths: res.tempFiles.map(f => f.tempFilePath), tempFiles })
      },
      fail: reject
    })
    // #endif
    
    // #ifdef H5
    // H5环境使用input file
    const input = document.createElement('input')
    input.type = 'file'
    input.accept = 'image/*'
    input.multiple = (options.count || defaultOptions.count) > 1
    
    input.onchange = (e) => {
      const files = Array.from(e.target.files)
      if (files.length === 0) {
        reject(new Error('未选择文件'))
        return
      }
      
      const tempFiles = []
      const tempFilePaths = []
      let loadedCount = 0
      
      files.forEach((file, index) => {
        const reader = new FileReader()
        reader.onload = (event) => {
          const dataUrl = event.target.result
          tempFiles.push({
            path: dataUrl,
            size: file.size,
            name: file.name,
            file: file
          })
          tempFilePaths.push(dataUrl)
          
          loadedCount++
          if (loadedCount === files.length) {
            resolve({ tempFilePaths, tempFiles })
          }
        }
        reader.onerror = reject
        reader.readAsDataURL(file)
      })
    }
    
    input.click()
    // #endif
    
    // #ifdef APP-PLUS
    // APP使用原生chooseImage
    uni.chooseImage({
      ...defaultOptions,
      ...options,
      success: (res) => {
        const tempFiles = res.tempFilePaths.map((path, index) => ({
          path: path,
          size: 0, // APP环境下无法直接获取文件大小
          name: `image_${Date.now()}_${index}.jpg`
        }))
        resolve({ ...res, tempFiles })
      },
      fail: reject
    })
    // #endif
  })
}

// 上传文件到服务器
export const uploadFile = (filePath, options = {}) => {
  return new Promise((resolve, reject) => {
    const token = uni.getStorageSync('token')
    const platformConfig = platform.getRequestConfig()
    
    // #ifdef H5
    // H5环境特殊处理
    if (filePath.startsWith('data:')) {
      // 将base64转换为File对象
      const arr = filePath.split(',')
      const mime = arr[0].match(/:(.*?);/)[1]
      const bstr = atob(arr[1])
      let n = bstr.length
      const u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      const file = new File([u8arr], options.name || 'upload.jpg', { type: mime })
      
      // 使用FormData上传
      const formData = new FormData()
      formData.append('file', file)
      
      // 使用原生fetch上传
      fetch(config.baseUrl + '/common/upload', {
        method: 'POST',
        headers: {
          'Authorization': token ? `Bearer ${token}` : '',
          'X-Platform': 'h5'
        },
        body: formData
      })
      .then(response => response.json())
      .then(data => {
        if (data.code === 200) {
          resolve(data)
        } else {
          reject(data)
        }
      })
      .catch(reject)
      
      return
    }
    // #endif
    
    // 其他平台使用uni.uploadFile
    uni.uploadFile({
      url: config.baseUrl + '/common/upload',
      filePath: filePath,
      name: 'file',
      header: {
        'Authorization': token ? `Bearer ${token}` : '',
        ...platformConfig.header
      },
      formData: {
        ...options.formData
      },
      success: (res) => {
        try {
          const data = JSON.parse(res.data)
          if (data.code === 200) {
            resolve(data)
          } else {
            reject(data)
          }
        } catch (e) {
          reject({ code: -1, msg: '上传响应解析失败' })
        }
      },
      fail: reject
    })
  })
}

// 批量上传图片
export const uploadImages = (tempFilePaths, options = {}) => {
  const uploadPromises = tempFilePaths.map((filePath, index) => {
    return uploadFile(filePath, {
      ...options,
      name: options.name || `image_${Date.now()}_${index}.jpg`
    })
  })
  
  return Promise.all(uploadPromises)
}

// 选择并上传图片
export const chooseAndUploadImage = (options = {}) => {
  return new Promise((resolve, reject) => {
    chooseImage(options)
      .then(res => {
        if (options.autoUpload !== false) {
          // 自动上传
          return uploadImages(res.tempFilePaths, options)
        } else {
          // 只选择不上传
          resolve(res)
        }
      })
      .then(uploadResults => {
        if (uploadResults) {
          resolve({
            uploadResults,
            urls: uploadResults.map(result => result.data?.url || result.url).filter(Boolean)
          })
        }
      })
      .catch(reject)
  })
}

// 压缩图片
export const compressImage = (filePath, quality = 0.8) => {
  return new Promise((resolve, reject) => {
    // #ifdef H5
    if (filePath.startsWith('data:')) {
      // H5环境下压缩base64图片
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      const img = new Image()
      
      img.onload = () => {
        const maxWidth = 1200
        const maxHeight = 1200
        let { width, height } = img
        
        // 计算压缩后的尺寸
        if (width > height) {
          if (width > maxWidth) {
            height = (height * maxWidth) / width
            width = maxWidth
          }
        } else {
          if (height > maxHeight) {
            width = (width * maxHeight) / height
            height = maxHeight
          }
        }
        
        canvas.width = width
        canvas.height = height
        
        ctx.drawImage(img, 0, 0, width, height)
        const compressedDataUrl = canvas.toDataURL('image/jpeg', quality)
        resolve(compressedDataUrl)
      }
      
      img.onerror = reject
      img.src = filePath
      return
    }
    // #endif
    
    // #ifdef APP-PLUS
    // APP环境使用plus.zip压缩
    plus.zip.compressImage({
      src: filePath,
      dst: filePath.replace(/\.[^.]+$/, '_compressed.jpg'),
      quality: Math.floor(quality * 100),
      overwrite: true
    }, resolve, reject)
    // #endif
    
    // #ifdef MP-WEIXIN
    // 小程序环境暂不支持压缩，直接返回原图
    resolve(filePath)
    // #endif
  })
}

// 获取图片信息
export const getImageInfo = (src) => {
  return new Promise((resolve, reject) => {
    uni.getImageInfo({
      src,
      success: resolve,
      fail: reject
    })
  })
}

export default {
  chooseImage,
  uploadFile,
  uploadImages,
  chooseAndUploadImage,
  compressImage,
  getImageInfo
}